tests: Add basic tests for ostree-prepare-root
authorWilliam Manley <will@williammanley.net>
Wed, 27 Jul 2016 15:40:05 +0000 (16:40 +0100)
committerAtomic Bot <atomic-devel@projectatomic.io>
Tue, 2 Aug 2016 19:07:25 +0000 (19:07 +0000)
These tests use unshare and mount to prepare a fake initrd/early boot
directory structure so we can then test ostree-prepare-root.

Things that are tested:

* Running in an initrd environment
* Running without initrd
* /var and /sysroot being mounted correctly
* /usr being mounted read-only

Things not tested (yet):

* Running as init - this could be accomplished by unsharing the pid
  namespace too.
* mounting/unmounting `/proc` if `/proc/cmdline` isn't available
* Persistent overlayfs for `/usr`
* Probably other things

The tests are basic but can be extended in the future as we do more work
on `ostree-prepare-root`.

These tests must be run as root as they require the ability to `mount`
and to `unshare` the mount namespace. Perhaps in the future we can use
user namespaces for this test once they are more widely available.

Closes: #403
Approved by: cgwalters

Makefile-tests.am
tests/libtest.sh
tests/test-switchroot.sh [new file with mode: 0755]

index 63d11ec80073287fb2504d2e7e6c65299a0f8a67..4316f2eeaddffd14d7e1f331dfaecbb58977cef4 100644 (file)
@@ -87,6 +87,7 @@ dist_test_scripts = \
        tests/test-prune.sh \
        tests/test-refs.sh \
        tests/test-demo-buildsystem.sh \
+       tests/test-switchroot.sh \
        $(NULL)
 
 if BUILDOPT_FUSE
index 2d064299cb93b5b8e09cce93b6084d7f71a60815..958f6769b15eb094a0a2b2e13b0c965491b44557 100755 (executable)
@@ -399,34 +399,25 @@ os_repository_new_commit ()
     cd ${test_tmpdir}
 }
 
+skip() {
+    echo "1..0 # SKIP" "$@"
+    exit 0
+}
+
 skip_without_user_xattrs () {
     touch test-xattrs
-    if ! setfattr -n user.testvalue -v somevalue test-xattrs; then
-        echo "1..0 # SKIP this test requires xattr support"
-        exit 0
-    fi
+    setfattr -n user.testvalue -v somevalue test-xattrs || \
+        skip "this test requires xattr support"
 }
 
 skip_without_fuse () {
-    if ! fusermount --version >/dev/null 2>&1; then
-        echo "1..0 # SKIP no fusermount"
-        exit 0
-    fi
+    fusermount --version >/dev/null 2>&1 || skip "no fusermount"
 
-    if ! capsh --print | grep -q 'Bounding set.*[^a-z]cap_sys_admin'; then
-       echo "1..0 # SKIP No cap_sys_admin in bounding set, can't use FUSE"
-        exit 0
-    fi
-
-    if ! [ -w /dev/fuse ]; then
-        echo "1..0 # SKIP no write access to /dev/fuse"
-        exit 0
-    fi
+    capsh --print | grep -q 'Bounding set.*[^a-z]cap_sys_admin' || \
+        skip "No cap_sys_admin in bounding set, can't use FUSE"
 
-    if ! [ -e /etc/mtab ]; then
-        echo "1..0 # SKIP no /etc/mtab"
-        exit 0
-    fi
+    [ -w /dev/fuse ] || skip "no write access to /dev/fuse"
+    [ -e /etc/mtab ] || skip "no /etc/mtab"
 }
 
 libtest_cleanup_gpg () {
diff --git a/tests/test-switchroot.sh b/tests/test-switchroot.sh
new file mode 100755 (executable)
index 0000000..e039f5b
--- /dev/null
@@ -0,0 +1,87 @@
+#!/bin/bash -ex
+
+this_script="${BASH_SOURCE:-$(readlink -f "$0")}"
+
+setup_bootfs() {
+       mkdir -p "$1/proc" "$1/bin"
+       echo "quiet ostree=/ostree/boot.0 ro" >"$1/proc/cmdline"
+       touch "$1/this_is_bootfs"
+       cp "$(dirname "$this_script")/../src/switchroot/ostree-prepare-root" "$1/bin"
+}
+
+setup_rootfs() {
+       mkdir -p "$1/ostree/deploy/linux/deploy/1334/sysroot" \
+                "$1/ostree/deploy/linux/deploy/1334/var" \
+                "$1/ostree/deploy/linux/deploy/1334/usr" \
+                "$1/ostree/deploy/linux/var" \
+                "$1/bin"
+       ln -s "deploy/linux/deploy/1334" "$1/ostree/boot.0"
+       ln -s . "$1/sysroot"
+       touch "$1/ostree/deploy/linux/deploy/1334/this_is_ostree_root" \
+             "$1/ostree/deploy/linux/var/this_is_ostree_var" \
+             "$1/ostree/deploy/linux/deploy/1334/usr/this_is_ostree_usr" \
+             "$1/this_is_real_root"
+       cp /bin/busybox "$1/bin"
+       busybox --list | xargs -n1 -I '{}' ln -s busybox "$1/bin/{}"
+       cp -r "$1/bin" "$1/ostree/deploy/linux/deploy/1334/"
+}
+
+enter_fs() {
+       cd "$1"
+       mkdir testroot
+       pivot_root . testroot
+       export PATH=$PATH:/sysroot/bin
+       cd /
+       umount -l testroot
+       rmdir testroot
+}
+
+find_in_env() {
+       tmpdir="$(mktemp -dt ostree-test-switchroot.XXXXXX)"
+       unshare -m <<-EOF
+               set -e
+               . "$this_script"
+               "$1" "$tmpdir"
+               enter_fs "$tmpdir"
+               ostree-prepare-root /sysroot
+               find /
+               touch /usr/usr_writable 2>/null \
+                       && echo "/usr is writable" \
+                       || echo "/usr is not writable"
+               touch /sysroot/usr/sysroot_usr_writable 2>/null \
+                       && echo "/sysroot/usr is writable" \
+                       || echo "/sysroot/usr is not writable"
+               EOF
+       rm -rf "$tmpdir"
+}
+
+setup_initrd_env() {
+       mount -t tmpfs tmpfs "$1"
+       setup_bootfs "$1"
+       mkdir "$1/sysroot"
+       mount -t tmpfs tmpfs "$1/sysroot"
+       setup_rootfs "$1/sysroot"
+}
+
+test_that_prepare_root_sets_sysroot_up_correctly_with_initrd() {
+       find_in_env setup_initrd_env >files
+
+       grep -qx "/this_is_bootfs" files
+       grep -qx "/sysroot/this_is_ostree_root" files
+       grep -qx "/sysroot/sysroot/this_is_real_root" files
+       grep -qx "/sysroot/var/this_is_ostree_var" files
+       grep -qx "/sysroot/usr/this_is_ostree_usr" files
+
+       grep -qx "/sysroot/usr is not writable" files
+       echo "ok ostree-prepare-root sets sysroot up correctly with initrd"
+}
+
+# This script sources itself so we only want to run tests if we're the parent:
+if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
+       . $(dirname $0)/libtest.sh
+       unshare -m true || \
+           skip "this test needs to set up mount namespaces, rerun as root"
+
+       echo "1..1"
+       test_that_prepare_root_sets_sysroot_up_correctly_with_initrd
+fi